/*--------begin change by wangwei----------*/
#include "test/startup.h"
#include "test/hz512.h"
#include "test/m_penuLoad.h"
#include "configs.h"
#include <config.h>
#include <typedefs.h>
#include <std_ops.h>
#include <status.h>
#include <error.h>
#include <beep.h>
#include <sampler.h>
#include <display_ui.h>
#include <display.h>

#include <exception.h>

#include <task_pub.h>
#include <tasks.h>

#include  <p_config.h>
#include  <p_status.h>
#include  <p_ui.h>

//the init function
/* //test
void *hz1_task(void *arg)
{
  while(1)
  {
  mLog("begin hz50_interrupt!\n");
  Task_wait_sig(DATA_AVAIL_SIG);
  }
  pthread_exit(NULL);
}
*/
void InitializeOS(void)
{
//Initialize Task ID of this task.  Must do it here since Task_init 
//never returns to Startup to return the task ID. 
  Status_Monitor_ID = pthread_self();
  Task_yield();
  mLog("1");
  MIO_Cmd_Task_ID = Task_create(MIO_CMD_NAME,NULL,N_ARGS,(void *)0);
  Task_sleep(30);

  mLog("2");
  RS232_Cmd_Task_ID = Task_create(RS232_CMD_NAME,NULL,N_ARGS,(void *)0);
  Task_sleep(30);

  mLog("3");
 UART_Task_ID = Task_create(UART_TASK_NAME,NULL,N_ARGS,(void *)0);
  Task_sleep(30);

  mLog("4");
  Signal_Buffer_Task_ID = Task_create(SIG_BUFFER_NAME,NULL,N_ARGS,(void *)0);
  Task_sleep(30);

  mLog("5");
  Gas_Pass_Task_ID = Task_create(GAS_PASS_NAME,NULL,N_ARGS,(void *)0);
  Task_sleep(30);

  mLog("6");
  Run_Task_ID = Task_create(RUN_TASK_NAME,NULL,N_ARGS,(void *)0);
  Task_sleep(30);

  mLog("7");
  TUI_Task_ID = Task_create(TUI_TASK_NAME,NULL,N_ARGS,(void *)0);
  Task_sleep(30);

  mLog("Task startup finished\n");

/* Finished with interrupts-off initialization.  Time to transfer      */
/* control to background and let this monster come alive!              */
   Initialization_Complete = TRUE;
   Power_On_Test_Complete  = TRUE;
//  StatusMonitor();
}

void DetermineInstConfig(void)
{
/* Configure the pneumatics and the power-fail oven and aux zone defaults.  */
/* NOTE:  If there is a pneumatics control board then it has already had    */
/* its FPGA downloaded so that communication with it is possible.           */

   /* Check for power-fail memory reset. */
   if (MF_Reset) /* Only reset manufacturing values if MF_Reset is indicated */
   {
      Oven_Type = REG_OVEN;
   }

   if ( PF_Reset == TRUE )
   {
      InitPneuConfig();  /* initialize data structures in non-volatile memory */
//      InitPwrFailOven_Zones();
   }

   /* Determine the pneumatics configuration by communicating with the   */
   /* pneumatics DSP.  Also initialize the pneumatics control variables. */
   /* NOTE: DeterminePneuConfig  will use the QSM               prior to */
   /* the generation of the 512 interrupt.                               */

   InitializePneumatics();  /* initialize data structures in volatile memory */
   DeterminePneuConfig();   /* read config info from module eeproms          */

   /* Now assign the Detector types sent to the Detector DSP */
   switch ( DetectorA_Config.type )
   {
   case FID:  case NPD: case LDID: case OEM_FID:
     DetectorA.type = SQRT_DETECTOR;
     break;
   case TCD:
     DetectorA.type = TCD_DETECTOR;
     break;
   case ECD:  case uECD:  case FPD:  case AIB: case OEM_AIB:
     DetectorA.type = LINEAR_DETECTOR;
     break;
   default:
     DetectorA.type = NULL_DETECTOR;
     break;
   }
   switch ( DetectorB_Config.type )
   {
   case FID:  case NPD: case LDID: case OEM_FID:
     DetectorB.type = SQRT_DETECTOR;
     break;
   case TCD:
     DetectorB.type = TCD_DETECTOR;
     break;
   case ECD:  case uECD:  case FPD:  case AIB: case OEM_AIB:
     DetectorB.type = LINEAR_DETECTOR;
     break;
   default:
     DetectorB.type = NULL_DETECTOR;
     break;
   }


}

int Startup(void)
{
  int ret = 0;
  int i = 0;
  unsigned short checksum = 0;
/* //test
  pthread_create(&Status_Monitor_ID,NULL,hz1_task,NULL);
  while(1)
  {
    sleep(1);
    Task_send_sig(DATA_AVAIL_SIG, Status_Monitor_ID);
   }
*/

   /* clear the latch used to tell hw about Start Runs */
  Detector_Adc_Image = 0;

//the Message Queueing mechanism used by p_ipc, p_pcbcom must be initialized.
//So, we will call QueueInit to initialize it now. 
  QueueInit(); 
 // Kludge- CheckIfPcbIsAlive uses the qsm to obtain the results of    
 // the pneu dsp's poweron self test.  As a debug tool, the pneumatics 
 // allows a command step (pause/continue of commands).  The use of    
 // of command stepping requires keyboard and display interactions. So 
 // to allow these interactions, the keyboard and display need to be   
 // initialized here.                                                  

   InitializeKeyboard();   /* Initialize the keyboard command system */
   InitializeDisplay();    /* Initialize the display */
   InitializeExceptions(); /* Clear all exceptions.  NOTE:  this must  */
                           /* be done here since FPGA loading          */
                           /* may set some exceptions.                 */
// Configure the SPI to Load pneuFPGA and pneuDSP;
  my_SPI_Init();
//NOTE:  The pneumatic FPGA **MUST** be loaded before the pneumatic   
//       DSP (if the Pneumatic Control Board is present).  The FPGA 
//       is used as a serial to parallel converter. 
// ALSO: Only the Pneumatic Control Board pulls the board present      
//       low; the Cheapo board does not.  The Cheapo board uses the    
//       DSP reset line, though, and needs it released to work.        
//       Therefore, InitializePneuDSP() is called regardless of the    
//       board present state to release the reset.  The routine will   
//       shift its load into space, but that's OK because it is dumb   
//       and can't tell whether the load was accepted anyway.          
  if(my_SPI_Load_pneuFPGA() == 0)
  {
    Pneu_FPGA_Status = 3;    /* New pneumatics board */
    my_SPI_Load_pneuDSP();

  } 
  else
  {    
    SetException( PNEU_FPGA_FAULT );
  }
//Init the 512 hz interrupt
  if(hz512_init()<0)
  {
    return -1;
  }
  Pneu_Dsp_Startup_Status = CheckIfPcbIsAlive();//CheckIfPcbIsAlive always return 1


// after load, Configure the SPI for communication with penuDSP;
  InitializeOnchipQSM(); 

/* See if we should skip the power-on DUART test */
/*       We skip the DUART tests if OC4          */
/* (bit 6 of PDR) is LOW (manufacturing test fixture uses this). */

   /* initialize poweron test results */
   Duart_Power_On_Status = PASSED;

/* set a flag letting us know that we are in an initialization section */
/* flow PCB2 communication path is dependant on the 512, this lets an      */
/* alternate mechanism be used                                         */

   Initialization_Complete = FALSE;

/* Set a flag letting us know that the power-on test is in progress.   */
/* And other flags letting us know that we have not completed the      */
/* zone power-on configuration or the detector offset measurement.     */

   Power_On_Test_Complete = FALSE;
   Zone_Power_On_Complete = FALSE;
   DataComm_Power_On_Complete = FALSE;
   Offset_Measurement_Complete = FALSE;

   InitializeKeyboard();     /* Initialize the keyboard command system */
   InitializeDisplay();      /* Initialize the display */
/* Initialize ramp table & ramp pointers in ramp info structure       */
/* CANNOT USE ANYTHING IN POWER FAIL RAM AS IT IS NOT INITIALIZED YET */

   InitRamps();
/* Initialize the Signal Path State and data store pointers.  This HAS */
/* to be done before UpdateInstStatus, which uses the pointers.        */

   InitializeSigPath();
/* before any of the pneu Get functions will operate, any cross-struct */
/* linkages must be initialized.                                       */

   LinkPneuStructs();

   if (PF_Check_Area_Valid == FALSE)
   {

//    Save the old HW config in the "check area" for use by            
//    InitializeMethod().  If memory contains garbage then this may    
//    save junk (depending on the junk in PF_Check_Area_Valid) :-)     
//    but if so it won't ever be used because PF_Reset should be TRUE  
//    and we'll use the default method instead of fixing-up the old    
//    one.                                                             

      Tower1.present = FALSE;      // Als tower presence always false at 
      Tower2.present = FALSE;      // poweron.  Status in PF ram in vireo, needs to be cleared
//      SavePwrFailInstConfig();
      PF_Check_Area_Valid = TRUE;  // protect "check area" until used 
   }


   /* read config information from pneumatics EEPROM */

//   GetEepromInfo();


 //  GetOEMDetFritFlags();     /* read the current HW config */
printf("DetermineInstConfig begin\n");
   DetermineInstConfig();    /* read the current HW config */
printf("DetermineInstConfig end\n");

   DetectorA_Config.host_model = TYPE_13_14_AS_IS; /* So fn CheckCheckArea in InitializeMethod will */
   DetectorB_Config.host_model = TYPE_13_14_AS_IS; /*  work properly                                */


   Parameter_Modified[0].byte = 0;
   Parameter_Modified[1].byte = 0;
   Parameter_Modified2[0].byte = 0;
   Parameter_Modified2[1].byte = 0;
   Parameter_Modified[0].bits.pwr_fail = 1;
   Parameter_Modified[1].bits.pwr_fail = 1;

   if (PF_Reset == TRUE )
   {
//      InitializePwrFailRAM();
      Parameter_Modified[0].bits.mem_reset = 1;
      Parameter_Modified[1].bits.mem_reset = 1;
   }
   else
   {

/*    Check to see that the Active_Wkfile is valid given the current   */
/*    configuration.  Default setpoints that are not valid and record  */
/*    corrections as exceptions.  Depends on InitializeExceptions()    */
/*    having already been called.                                      */

//      InitializeMethod();
   }
/* Now we have a valid method:  either a default one from a memory     */
/* reset or the previous one that has had differences resolved between */
/* former and current HW configurations.  So we have no further need   */
/* for the "check area" used to hold the old HW config.                */

   PF_Check_Area_Valid = FALSE;

   InitializeCmdProc();         /* initialize the command processor */


/* We need to copy the setpoints from the Active Workfile              */
/* over to the status (working) copies *and* write them out to the     */
/* hardware.                                                           */
   UpdateInstStatus();

/* Initialize the GLP deviation, diagnostic task, readiness & fault monitors */

   InitializeStatusMonitor();

/* Initialize the run state machine */

   InitializeRunControl();

/* Initialize Ramp Generator Structures, must be done before calc run length */
/* MOVED TO DETERMINE INSTRUMENT CONFIG                                      */
/* InitRamps(); */

/* Initialize the run length value */

   CalcRunLength();

/* Initialize the Real Time Clock hardware     */
/*  NOTE: this doesn't affect the time setting */
/*    but MUST be after InitPowerFailRam       */

//   InitializeRealTimeClock();   /* MUST be before ResetClockTablePointer */

/* reset pointers for time tables */

//   ResetRunTablePointer();
//   ResetClockTablePointer();
   PneuStartup();
printf("write eeprom begin---------------------------\n");
//  InitDetEEPROM(2,EPC_FID,0xa854,0x00a0,0x0000,0x0001,0xc282);
printf("write eeprom end---------------------------\n");
/*
for(i=1;i<256;i++)
{
  unsigned short value;
  ReadEeprom( 2, i, &value );
  checksum +=value;
}
  printf("\nchecksum =%4x \n",checksum);
  ReadEeprom( 2, 0, &checksum );
  printf("the read checksum=%4x \n",checksum);
*/

  InitConfig();//init the configs
  UART_init();
  TUI_init();

  InitializeOS();
  return 0;
}

/*--------end change----------------------*/
